﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using Lswweb.Model;

namespace Lswweb.Domain
{
    public class ImageHelper
    {
        #region 缩略图

        /// <summary>
        /// 取得图片缩略图
        /// </summary>
        /// <param name="maxSize">缩略图高宽最大大小</param>
        /// <param name="imageUrl">要生成缩略图片url</param>
        /// <returns>缩略图url</returns>
        public static string CreateThumbnail(int maxSize, string imageUrl)
        {
            string imagePath = Globals.GetFilePath(imageUrl);
            if (!Globals.FileExists(imagePath))
                return string.Empty;

            int height=maxSize, width=maxSize;
            Image image = Image.FromFile(imagePath);
            if (image.Height > image.Width)
            {
                height = maxSize;
                width = (int)(image.Width * ((decimal)maxSize / image.Height));
            }
            else
            {
                width = maxSize;
                height = (int)(image.Height * ((decimal)maxSize / image.Width));
            }

            Image thumbnailImage = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(thumbnailImage);
            g.Clear(Color.White);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            g.DrawImage(image, new Rectangle(0, 0, width, height), new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel);

            string thumbnailUrl = GetThumbnailUrl(imageUrl, false);
            string thumbnialPath = Globals.GetFilePath(thumbnailUrl);

            try
            {
                SaveHighImage(thumbnailImage as Bitmap,thumbnialPath,10000);
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                image.Dispose();
                thumbnailImage.Dispose();
                g.Dispose();
            }

            return thumbnailUrl;
        }
        public static string CreateThumbnail(string imageUrl)
        {
            return CreateThumbnail(SiteSettings.Settings.ThumbnailMaxSize,imageUrl);
        }
        private static ImageCodecInfo GetEncoderInfo(string mineType)
        {

            ImageCodecInfo[] myEncoders =ImageCodecInfo.GetImageEncoders();

            foreach (ImageCodecInfo myEncoder in myEncoders)
                if (myEncoder.MimeType == mineType)
                    return myEncoder;
            return null;
        }


        /// <summary>
        /// 取得缩略图的url，如果缩略图不存在那么就生成缩略图
        /// </summary>
        /// <param name="imageUrl">图片url</param>
        /// <param name="isCreateThumbnail">如果缩略图不存在是否生成缩略图</param>
        /// <returns></returns>
        public static string GetThumbnailUrl(string imageUrl, bool isCreateThumbnail)
        {

            if (string.IsNullOrEmpty(imageUrl) || !Globals.FileExists(imageUrl))
                return Globals.GetSkinPath("/Images/nopic.gif");

            string[] labels = imageUrl.Split('.');
            string url = imageUrl.Replace("." + labels[labels.Length - 1], "_Thumbnail.jpg");

            if (!isCreateThumbnail)
                return url;

            if (!Globals.FileExists(url))
                CreateThumbnail(imageUrl);
            return url;
        }

        #endregion

        #region 水印

        public static void MakeWatermark(string watermarkText, string watermarkImageUrl, string photoUrl)
        {
            MakeWatermark(watermarkText,watermarkImageUrl,photoUrl,string.Empty);
        }
        /// <summary>
		/// 给图片加入水印
		/// </summary>
        /// <param name="watermarkText">需要写入的水印文字</param>
        /// <param name="watermarkImageUrl">需要加入成水印的图片url</param>
		/// <param name="photoPath">需要添加水印的图片的路径</param>
		/// <param name="savePhotoPath">保存的图片路径，为空则覆盖原图片</param>
        public static void MakeWatermark(string watermarkText, string watermarkImageUrl, string photoUrl, string savePhotoUrl)
        {
            photoUrl = Globals.GetFilePath(photoUrl);
            if (string.IsNullOrEmpty(savePhotoUrl))
                savePhotoUrl = photoUrl;
            else
                savePhotoUrl = Globals.GetFilePath(savePhotoUrl);
            if(!string.IsNullOrEmpty(watermarkImageUrl))
                watermarkImageUrl=Globals.GetFilePath(watermarkImageUrl);

            if (!Globals.FileExists(photoUrl))
                throw new IOException(string.Format("文件{0}不存在!", photoUrl));

            //创建一个image对象,即要被处理的图片
            Image image = Image.FromFile(photoUrl);
            int phWidth = image.Width;
            int phHeight = image.Height;

            Image imgPhoto = new Bitmap(phWidth,phHeight);
            
            Graphics grPhoto = Graphics.FromImage(imgPhoto);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
            grPhoto.SmoothingMode = SmoothingMode.HighQuality;
            grPhoto.PixelOffsetMode = PixelOffsetMode.HighQuality;
            grPhoto.CompositingQuality = CompositingQuality.HighQuality;
            grPhoto.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            grPhoto.Clear(Color.White);
            grPhoto.DrawImage(image, new Rectangle(0, 0, phWidth, phWidth), new Rectangle(0, 0, phWidth, phWidth), GraphicsUnit.Pixel);

            image.Dispose();

            //添加文字水印
            if (!string.IsNullOrEmpty(watermarkText))
            {
                //字体大小数组中.
                int[] sizes = new int[] { 48, 32, 24, 18, 14, 12, 10, 8 };

                Font crFont = null;
                SizeF crSize = new SizeF();

                //循环测试数组中所定义的字体大小是否适合版权信息,如果合适就使用此种字体大小
                for (int i = 0; i < 6; i++)
                {
                    //设置字体类型,可以单独提出,作为参数
                    crFont = new Font("宋体", sizes[i], FontStyle.Bold);
                    //测量此种字体大小
                    crSize = grPhoto.MeasureString(watermarkText, crFont);

                    if ((ushort)crSize.Width < (ushort)(phWidth / 2))
                        break;
                }

                //给底部保留%3的空间
                int yPixlesFromBottom = (int)(phHeight * .03);

                //设置字体在图片中的位置
                float yPosFromBottom = phHeight - yPixlesFromBottom - crSize.Height;

                float xCenterOfImg = (phWidth / 2);
                //设置字体居中
                StringFormat StrFormat = new StringFormat();
                StrFormat.Alignment = StringAlignment.Center;

                //设置绘制文本的颜色和纹理 (Alpha=153)
                SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));

                //将版权信息绘制到图象上
                grPhoto.DrawString(watermarkText,                     //版权信息
                    crFont,                                       //字体
                    semiTransBrush2,                              //绘制文本的颜色及纹理
                    new PointF(xCenterOfImg + 1, yPosFromBottom + 1),  //绘制文本的位置
                    StrFormat);                                   //格式

                //设置绘制文本的颜色和纹理 (Alpha=153)
                SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));

                //重新绘制版权信息,以让其具有阴影效果
                //将文本向又下移动一个象素
                grPhoto.DrawString(watermarkText,                 //版权信息
                    crFont,                                   //字体
                    semiTransBrush,                           //绘制文本的颜色及纹理
                    new PointF(xCenterOfImg, yPosFromBottom),  //绘制文本的位置
                    StrFormat);  //格式
            }

            
            //添加图片水印
            if (!string.IsNullOrEmpty(watermarkImageUrl))
            {
                //创建一个需要填充水银的Image对象
                Image imgWatermark = new Bitmap(watermarkImageUrl);
                int wmWidth = imgWatermark.Width;
                int wmHeight = imgWatermark.Height;


                //在原来修改过的bmPhoto上创建一个水银位图
                Bitmap bmWatermark = new Bitmap(imgPhoto);
                bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
                //将位图bmWatermark加载到Graphics对象
                Graphics grWatermark = Graphics.FromImage(bmWatermark);

                ImageAttributes imageAttributes = new ImageAttributes();

                ColorMap colorMap = new ColorMap();

                colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
                colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

                ColorMap[] remapTable = { colorMap };

                imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

                float[][] colorMatrixElements = { 
                                                new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},       
                                                new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},        
                                                new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},        
                                                new float[] {0.0f,  0.0f,  0.0f,  0.3f, 0.0f},        
                                                new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}};
                ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);

                imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default,
                    ColorAdjustType.Bitmap);

                int xPosOfWm = ((phWidth - wmWidth) - 10);
                int yPosOfWm = 10;

                grPhoto.DrawImage(imgWatermark,
                    new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight),  //Set the detination Position
                    0,                  // x-coordinate of the portion of the source image to draw. 
                    0,                  // y-coordinate of the portion of the source image to draw. 
                    wmWidth,            // Watermark Width
                    wmHeight,		    // Watermark Height
                    GraphicsUnit.Pixel, // Unit of measurment
                    imageAttributes);   //ImageAttributes Object
            }
            
            try
            {
                SaveHighImage(imgPhoto as Bitmap, savePhotoUrl, 10000);
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                imgPhoto.Dispose();
                grPhoto.Dispose();
            }
        }

	
        #endregion

        #region 移动图片到指定目录

        /// <summary>
        /// 从字符串中提取图片路径，并移动到指定的目录
        /// </summary>
        /// <param name="editorValue">字符串信息</param>
        /// <returns>更换过图片路径后的新字符串信息</returns>
        public static string MoveEditorImagesToDirectory(string editorValue, string imageDirectory)
        {
            if (string.IsNullOrEmpty(editorValue))
                return editorValue;

            IList<string> images = Globals.RegexImagesUrl(editorValue);
            foreach (string imageUrl in images)
            {
                if (imageUrl.ToLower().IndexOf("http://") > 0
                    ||imageUrl.IndexOf(SiteSettings.Settings.FCKeditorUploadFileDirectory) == -1)
                    continue;

                string newUrl = MoveImagesToDirectory(imageUrl,imageDirectory);
                editorValue = editorValue.Replace(imageUrl, newUrl);
            }
            return editorValue;
        }
        public static string MoveEditorImagesToDirectory(SiteModule siteModule, string editorValue)
        {
            string directory = SiteSettings.GetUploadDirectory(siteModule);
            return MoveEditorImagesToDirectory(editorValue, directory);
        }

        /// <summary>
        /// 移动文件到指定的目录
        /// </summary>
        /// <param name="fileUrl">文件url</param>
        /// <returns>指定目录的url</returns>
        public static string MoveImagesToDirectory(string fileUrl,string imageDirectory)
        {
            string fileName = Path.GetFileName(fileUrl);
            string newUrl = imageDirectory + fileName;
            if (newUrl == fileUrl)
                return fileUrl;

            if (!Globals.FileExists(fileUrl))
            {
                if (Globals.FileExists(newUrl))
                    return newUrl;
                else
                    return fileUrl;
            }

            if (Globals.FileExists(newUrl))
                newUrl = newUrl.Replace(fileName, Globals.RandomStr(6) + fileName);

            string newPath = Globals.GetFilePath(newUrl);
            string oldPath = Globals.GetFilePath(fileUrl);

            Globals.DirectoryExists(imageDirectory, true);
            File.Move(oldPath, newPath);
            return newUrl;
        }
        public static string MoveImagesToDirectory(SiteModule siteModule, string fileUrl)
        {
            string directory = SiteSettings.GetUploadDirectory(siteModule);
            return MoveImagesToDirectory(fileUrl, directory);
        }

        #endregion

        #region other

        /// <summary>
        /// 保存高质图片
        /// </summary>
        /// <param name="bmp"></param>
        /// <param name="savePath">保存路径</param>
        /// <param name="quality">质量参数(0-100)</param>
        public static void SaveHighImage(Bitmap bmp, string savePath, int quality)
        {
            EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
            EncoderParameter encoderParam = new EncoderParameter(Encoder.Quality, quality);
            encoderParams.Param[0] = encoderParam;

            ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo imageCode in arrayICI)
            {
                string extension = Path.GetExtension(savePath).ToUpper();
                if (imageCode.FilenameExtension.IndexOf(extension)>=0)
                {
                    bmp.Save(savePath, imageCode, encoderParams);
                    return;
                }
            }

            bmp.Save(savePath, GetImageFormat(savePath));
        }

        /// <summary>
        /// 根据文件名取得图片的格式方式
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        private static ImageFormat GetImageFormat(string imagePath)
        {
            string[] ex = imagePath.Split('.');
            switch (ex[ex.Length - 1].ToLower())
            {
                case "gif" :
                    return ImageFormat.Gif;
                case "png" :
                    return ImageFormat.Png;
                case "bmp" :
                    return ImageFormat.MemoryBmp;
                case "ioc" :
                    return ImageFormat.Icon;
                case "jpg":
                case "jpeg":
                default :
                    return ImageFormat.Jpeg;
            }
        }

        #endregion
    }
}
